home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include "global.h"
- #include "config.h"
- #include "mbuf.h"
- #include "proc.h"
- #include "iface.h"
- #include "ip.h"
- #include "netuser.h"
- #include "ax25.h"
- #include "enet.h"
- #include "pktdrvr.h"
- #include "cmdparse.h"
- #include "commands.h"
- #ifdef CRCSET
- #include "crc.h"
- static int ifcrc __ARGS((int argc,char *argv[],void *p));
- #endif
-
- /* Loopback pseudo-interface */
- struct iface Loopback = {
- &Encap, /* Link to next entry */
- "loopback", /* name */
- CL_NONE, /* type */
- &Iftypes[0], /* iftype */
- 0x7f000001L, /* addr 127.0.0.1 */
- 0xffffffffL, /* broadcast 255.255.255.255 */
- 0xffffffffL, /* netmask 255.255.255.255 */
- NULL, /* (*ioctl) */
- NULLFP, /* (*iostatus) */
- NULLFP, /* (*send) */
- NULLFP, /* (*output) */
- NULLFP, /* (*raw) */
- NULLFP, /* (*stop) */
- NULLFP, /* (*status) */
- MAXINT16, /* mtu No limit */
- 0, /* dev */
- 0, /* xdev */
- 0, /* port */
- /* 0, /* flags */
- 0, /* trace */
- NULLCHAR, /* trfile */
- NULLFILE, /* trfp */
- NULLCHAR, /* hwaddr */
- NULLIF, /* forw */
- 0, /* ipsndcnt */
- 0, /* rawsndcnt */
- 0, /* iprcvcnt */
- 0, /* rawrcvcnt */
- 0, /* lastsent */
- 0, /* lastrecv */
- NULLPROC, /* rxproc */
- NULLPROC, /* txproc */
- NULLPROC, /* supv */
- #ifdef CRCSET
- 0, /* sendcrc */
- 0, /* crcerrors */
- #endif
- NULL, /* extension */
- 0,
- NULLLQ,
- MAXDEFAULT,
- 0,
- };
-
- /* Encapsulation pseudo-interface */
- struct iface Encap = {
- NULLIF,
- "encap", /* name */
- CL_NONE, /* type */
- &Iftypes[0], /* iftype */
- INADDR_ANY, /* addr 0.0.0.0 */
- 0xffffffffL, /* broadcast 255.255.255.255 */
- 0xffffffffL, /* netmask 255.255.255.255 */
- NULL, /* (*ioctl) */
- NULLFP, /* (*iostatus) */
- ip_encap, /* (*send) */
- NULLFP, /* (*output) */
- NULLFP, /* (*raw) */
- NULLFP, /* (*stop) */
- NULLFP, /* (*status) */
- MAXINT16, /* mtu No limit */
- 0, /* dev */
- 0, /* xdev */
- 0, /* port */
- /* 0, /* flags */
- 0, /* trace */
- NULLCHAR, /* trfile */
- NULLFILE, /* trfp */
- NULLCHAR, /* hwaddr */
- NULLIF, /* forw */
- 0, /* ipsndcnt */
- 0, /* rawsndcnt */
- 0, /* iprcvcnt */
- 0, /* rawrcvcnt */
- 0, /* lastsent */
- 0, /* lastrecv */
- NULLPROC, /* rxproc */
- NULLPROC, /* txproc */
- NULLPROC, /* supv */
- #ifdef CRCSET
- 0, /* sendcrc */
- 0, /* crcerrors */
- #endif
- NULL, /* extension */
- 0,
- NULLLQ,
- MAXDEFAULT,
- 0,
- };
-
- /* Interface list header */
- struct iface *Ifaces = &Loopback;
-
- char Badif[] = "Interface %s unknown\n";
- char Badax[] = "Interface %s not AX25\n";
- char Noipaddr[] = "IP adress not set\n";
- char Ifexist[] = "Interface %s already exists\n";
-
- static int near mask2width __ARGS((int32 mask));
- static void showiface __ARGS((struct iface *ifp));
-
- #ifdef AX25
- void
- init_flags(struct iface *ifp)
- {
- ifp->flags = mxallocw(sizeof(struct flags));
- ifp->flags->maxframe = Maxframe;
- ifp->flags->t1init = T1init;
- ifp->flags->t2init = T2init;
- ifp->flags->t3init = T3init;
- ifp->flags->t4init = T4init;
- ifp->flags->t5init = T5init;
- ifp->flags->t6init = T6init; /* DAMA timeout */
- ifp->flags->retries = Retries;
- ifp->flags->axwindow = Axwindow;
- ifp->flags->paclen = Paclen;
- ifp->flags->pthresh = Pthresh;
- ifp->flags->digipeat = Digipeat;
- ifp->flags->t3disc = T3disc;
- ifp->flags->dama_slave = 0; /* DAMA slave flag */
- ifp->flags->dama_busy = 0; /* wait until poll */
- }
- #endif
-
- /* Given a network mask, return the number of contiguous 1-bits starting
- * from the most significant bit.
- */
- static int near
- mask2width(int32 mask)
- {
- int i, width = 0;
-
- for(i = 31;i >= 0;i--) {
- if(!(mask & (1L << i)))
- break;
- width++;
- }
- return width;
- }
-
- /* Set interface IP address */
- static int
- ifipaddr(int argc,char *argv[],void *p)
- {
- struct iface *ifp = p;
-
- if((ifp->addr = resolve(argv[1])) == 0) {
- tprintf(Badhost,argv[1]);
- return -1;
- }
- return 0;
- }
-
- /* Set link (hardware) address */
- static int
- iflinkadr(int argc,char *argv[],void *p) {
- struct iface *ifp = p;
-
- if(ifp->iftype == NULLIFT || ifp->iftype->scan == NULL){
- tputs("Can't set link address\n");
- return -1;
- }
- if(ifp->hwaddr != NULLCHAR)
- xfree(ifp->hwaddr);
- ifp->hwaddr = mxallocw(ifp->iftype->hwalen);
- if(*ifp->iftype->scan != 0)
- return (*ifp->iftype->scan)(ifp->hwaddr,argv[1]);
- return 0;
- }
-
- /* Set interface broadcast address. This is actually done
- * by installing a private entry in the routing table.
- */
- static int
- ifbroad(int argc,char *argv[],void *p) {
- struct iface *ifp = p;
- struct route *rp;
-
- if((rp = rt_blookup(ifp->broadcast,32)) != NULLROUTE && rp->iface == ifp)
- rt_drop(ifp->broadcast,32);
- if((ifp->broadcast = resolve(argv[1])) == 0) {
- tprintf(Badhost,argv[1]);
- return -1;
- }
- rt_add(ifp->broadcast,32,0L,ifp,1L,0L,1);
- return 0;
- }
-
- static int
- ifname(int argc,char *argv[],void *p) {
- struct iface *ifp = p;
-
- if(ifp->name != NULLCHAR)
- xfree(ifp->name);
- ifp->name = strxdup(argv[1]);
- return 0;
- }
-
- /* Set the network mask. This is actually done by installing
- * a routing entry.
- */
- static int
- ifnetmsk(int argc,char *argv[],void *p) {
- struct iface *ifp = p;
- struct route *rp;
-
- /* Remove old entry if it exists */
- if((rp = rt_blookup(ifp->addr & ifp->netmask,mask2width(ifp->netmask))) != NULLROUTE)
- rt_drop(rp->target,rp->bits);
- ifp->netmask = htol(argv[1]);
- rt_add(ifp->addr,mask2width(ifp->netmask),0L,ifp,0L,0L,0);
- return 0;
- }
-
- /* Command to set interface encapsulation mode */
- static int
- ifencap(int argc,char *argv[],void *p) {
- struct iface *ifp = p;
-
- if(setencap(ifp,argv[1]) != 0) {
- tprintf("Encap mode %s unknown\n",argv[1]);
- return 1;
- }
- return 0;
- }
- /* Function to set encapsulation mode */
- int
- setencap(struct iface *ifp,char *mode) {
- struct iftype *ift;
-
- for(ift = &Iftypes[0];ift->name != NULLCHAR;ift++)
- if(strnicmp(ift->name,mode,strlen(mode)) == 0)
- break;
- if(ift->name == NULLCHAR)
- return -1;
- ifp->iftype = ift;
- ifp->send = ift->send;
- ifp->output = ift->output;
- ifp->type = ift->type;
- return 0;
- }
-
- /* Set interface Maximum Transmission Unit */
- static int
- ifmtu(int argc,char *argv[],void *p)
- {
- struct iface *ifp = p;
-
- ifp->mtu = atoi(argv[1]);
- return 0;
- }
-
- /* Set interface forwarding */
- static int
- ifforw(int argc,char *argv[],void *p) {
- struct iface *ifp = p;
-
- if((ifp->forw = if_lookup(argv[1])) == NULLIF)
- return -1;
- if(ifp->forw == ifp)
- ifp->forw = NULLIF;
- return 0;
- }
- #ifdef CRCSET
-
- static int
- ifcrc(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *ifp = p;
- return setbool(&ifp->sendcrc, "CRC generation",argc,argv);
- }
- #endif
-
- /* Display the parameters for a specified interface */
- static void
- showiface(struct iface *ifp) {
- char tmp[25];
-
- tprintf("%-10s IP addr %s MTU %u Link encap ",
- ifp->name,inet_ntoa(ifp->addr),(int)ifp->mtu);
- if(ifp->iftype == NULLIFT){
- tputs("not set\n");
- } else {
- tprintf("%s\n",ifp->iftype->name);
- if(ifp->iftype->format != NULL && ifp->hwaddr != NULLCHAR)
- tprintf("%20s %s\n","Link addr",(*ifp->iftype->format)(tmp,ifp->hwaddr));
- }
- tprintf("%16s 0x%x netmask 0x%08lx\n","trace",ifp->trace,ifp->netmask);
- tprintf("%19s %lu tot %lu idle %s\n",
- "sent: ip",ifp->ipsndcnt,ifp->rawsndcnt,tformat(secclock() - ifp->lastsent));
- tprintf("%19s %lu tot %lu idle %s\n",
- "recv: ip",ifp->iprecvcnt,ifp->rawrecvcnt,tformat(secclock() - ifp->lastrecv));
- if(ifp->forw != NULLIF)
- tprintf("%28s %s\n","output forward to",ifp->forw->name);
- if (ifp->flags) {
- tprintf("%-10s DAMA slave o"," ");
- if (ifp->flags->dama_slave)
- tprintf("n with %u connection(s)\n",ifp->flags->dama_slave);
- else
- tputs("ff\n");
- #ifdef CRCSET
- tprintf(" CRC %s errors %lu\n",
- ifp->sendcrc ? "enabled" : "disabled",ifp->crcerrors);
- #endif
- }
- }
-
- /* Command to detach an interface */
- int
- dodetach(int argc,char *argv[],void *p) {
- struct iface *ifp;
-
- if((ifp = if_lookup(argv[1])) == NULLIF){
- tprintf(Badif,argv[1]);
- return 1;
- }
- if(if_detach(ifp) == -1)
- tputs("Can't detach loopback interface\n");
- return 0;
- }
- /* Detach a specified interface */
- int
- if_detach(struct iface *ifp) {
- struct iface *iftmp;
- struct route *rp,*rptmp;
- int i,j;
-
- if(ifp == &Loopback || ifp == &Encap)
- return -1;
-
- /* Drop all routes that point to this interface */
- if(R_default.iface == ifp)
- rt_drop(0L,0); /* Drop default route */
-
- for(i = 0; i < HASHMOD; i++) {
- for(j = 0; j < 32; j++) {
- for(rp = Routes[j][i];rp != NULLROUTE;rp = rptmp){
- /* Save next pointer in case we delete this entry */
- rptmp = rp->next;
- if(rp->iface == ifp)
- rt_drop(rp->target,rp->bits);
- }
- }
- }
- /* Unforward any other interfaces forwarding to this one */
- for(iftmp = Ifaces;iftmp != NULLIF;iftmp = iftmp->next){
- if(iftmp->forw == ifp)
- iftmp->forw = NULLIF;
- }
-
- /* Call device shutdown routine, if any */
- if(ifp->stop != NULLFP)
- (*ifp->stop)(ifp,0);
-
- killproc(ifp->proc);
- killproc(ifp->proc1);
- killproc(ifp->supv);
-
- /* Free allocated memory associated with this interface */
- if(ifp->name != NULLCHAR)
- xfree(ifp->name);
- if(ifp->hwaddr != NULLCHAR)
- xfree(ifp->hwaddr);
-
- /* Remove from interface list */
- if(ifp == Ifaces){
- Ifaces = ifp->next;
- } else {
- /* Search for entry just before this one
- * (necessary because list is only singly-linked.)
- */
- for(iftmp = Ifaces;iftmp != NULLIF ;iftmp = iftmp->next)
- if(iftmp->next == ifp)
- break;
- if(iftmp != NULLIF && iftmp->next == ifp)
- iftmp->next = ifp->next;
- }
- if(ifp->lq != NULLLQ)
- xfree(ifp->lq);
-
- /* Finally free the structure itself */
- xfree((char *)ifp);
- return 0;
- }
-
- /* Given the ascii name of an interface, return a pointer to the structure,
- * or NULLIF if it doesn't exist
- */
- struct iface *
- if_lookup(char *name) {
- struct iface *ifp;
-
- for(ifp = Ifaces; ifp != NULLIF; ifp = ifp->next)
- if(strcmp(ifp->name,name) == 0)
- return ifp;
- return NULLIF;
- }
-
- /* Return iface pointer if 'addr' belongs to one of our interfaces,
- * NULLIF otherwise.
- * This is used to tell if an incoming IP datagram is for us, or if it
- * has to be routed.
- */
- struct iface *
- ismyaddr(int32 addr) {
- struct iface *ifp;
-
- for(ifp = Ifaces; ifp != NULLIF; ifp = ifp->next)
- if(addr == ifp->addr)
- return ifp;
- return NULLIF;
- }
-
- /* return buffer with name + comment */
- char *
- if_name(struct iface *ifp,char *comment) {
- char *result = mxallocw(strlen(ifp->name) + strlen(comment) + 2);
-
- sprintf(result,"%s%s",ifp->name,comment);
- return result;
- }
-
- #ifdef ASY
- /* Raw output routine that tosses all packets. Used by dialer, tip, etc */
- int
- bitbucket(struct iface *ifp,struct mbuf *bp) {
- free_p(bp);
- return 0;
- }
- #endif
-
- /* Set interface parameters */
- int
- doifconfig(int argc,char *argv[],void *p) {
- struct iface *ifp;
- int i;
-
- struct cmds Ifcmds[] = {
- "broadcast", ifbroad, 0, 2, NULLCHAR,
- #ifdef CRCSET
- "crc", ifcrc, 0, 2, NULLCHAR,
- #endif
- "encapsulation", ifencap, 0, 2, NULLCHAR,
- "forward", ifforw, 0, 2, NULLCHAR,
- "ipaddress", ifipaddr, 0, 2, NULLCHAR,
- "linkaddress", iflinkadr, 0, 2, NULLCHAR,
- "mtu", ifmtu, 0, 2, NULLCHAR,
- "name", ifname, 0, 2, NULLCHAR,
- "netmask", ifnetmsk, 0, 2, NULLCHAR,
- NULLCHAR,
- };
-
- if(argc < 2){
- for(ifp = Ifaces;ifp != NULLIF;ifp = ifp->next)
- showiface(ifp);
- return 0;
- }
- if((ifp = if_lookup(argv[1])) == NULLIF){
- tprintf(Badif,argv[1]);
- return -1;
- }
- if(argc == 2){
- showiface(ifp);
- if ( ifp->status != NULLFP ) {
- (*ifp->status)(ifp);
- }
- return 0;
- }
- if(argc == 3){
- tputs("Argument missing\n");
- return -1;
- }
- for(i=2;i<argc-1;i+=2)
- subcmd(Ifcmds,3,&argv[i-1],ifp);
-
- return 0;
- }
-